package com.ceolt.dao.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.ceolt.dao.IBaseTermDao;
import com.ceolt.entity.Vocabulary;
import com.ceolt.entity.Word;

/**
 * @author yejf
 *
 */
public class BaseTermDaoImpl implements IBaseTermDao {

	/* (non-Javadoc)
	 * @see com.tz.cels.dao.IBaseTermDao#getAllWords()
	 */
	@Override
	public Set<Word> getAllWords() {
		Set<Word> words = new TreeSet<>();
		//1.要判断原始的单词数据文件是否存在
		File wordFile = new File(WORD_FILE);
		//2.
		if(!wordFile.exists()){
			System.out.println("单词数据文件不存在:"+wordFile);
			return null;
		}
		//如果存在,则处理这个文件.
		BufferedReader br = null;
		StringBuilder builder = new StringBuilder(); //用来保存读到的数据
		
		try {
//			br = new BufferedReader(new FileReader(wordFile));
			//解决编解码问题
			br = new BufferedReader(new InputStreamReader(new FileInputStream(wordFile), "UTF-8"));
			//定义变量来保存每一行数据
			String line = null;
			//循环读取
			while((line = br.readLine()) != null){
				//处理每一行
				String[] temp = line.split("\\s+");
				//依次取出英文和中文
				String en = temp[0];
				//处理一下这个英文，首字母大写，其它全部小字
				builder.append(en.toLowerCase());
				//把首字母大写
				builder.setCharAt(0, (char)(builder.charAt(0)-32));
				//接下来处理中文
				String cnTemp = temp[1].trim();
				//把中文解释切割成字符串数组
				String[] cn = cnTemp.split(":");
				//创建一个 Word 对象
				Word w = new Word(en, cn);
				//把这个对象添加到集合中
				words.add(w);
				//清空 builder对象
				builder.delete(0, builder.capacity());
			}
			//输出一句日志
			System.out.println(">>>加载单词文件成功.");
		} catch (IOException e) {
			e.printStackTrace();
			//出现异常要返回 null; 
			return null;
		} finally {
			//释放资源
			try {
				if(br != null) br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return words;
	}

	/* (non-Javadoc)
	 * @see com.tz.cels.dao.IBaseTermDao#getAllVocabularies()
	 */
	@Override
	public Set<Vocabulary> getAllVocabularies() {
		Set<Vocabulary> vSet = new TreeSet<>();
		//1.判断原始词汇文件是否存在
		File vFile = new File(VOCABULARY_FILE);
		//判断
		if(!vFile.exists()){
			System.out.println("词汇文件不存在:"+vFile);
			return null;
		}
		//利用io字符流来读取
		BufferedReader br = null;
		String line = null;
		try {
			//br = new BufferedReader(new FileReader(vFile));
			br = new BufferedReader(new InputStreamReader(new FileInputStream(vFile), "UTF-8"));
			//循环读取每一行
			while((line = br.readLine()) != null){
				//处理每一行
				String[] temp = line.split("#");
				//拿出每一部份
				String en = temp[0];
				String[] cn = temp[1].split(":");
				//先利用 en和cn创建 Vocabulary 对象
				Vocabulary v = new Vocabulary(en, cn);
				//对于词汇，要考虑是否有  简称 [acronym]
				if(temp.length == 3){
					//说明,这个词汇有简称
					v.setAcronym(temp[2]);
				}
				//把这个对象添加到集合中
				vSet.add(v);
			}
			//输出一句日志
			System.out.println(">>>读取词汇文件成功.");
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if(br != null) br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//返回
		return vSet;
	}

	/* 
	 * 此方法是把 Map对象序列化到 指定的文件名中,
	 * 利用 ObjectOutputStream 来完成序列化的工作
	 * @see com.tz.cels.dao.IBaseTermDao#writeToFile(java.util.Map, java.lang.String)
	 */
	@Override
	public void writeToFile(Map<String, String> map, String fileName) {
		//1.创建 File对象
		File file = new File(fileName);
		//2.判断此file是否是文件
		if(file.isDirectory()){
			System.out.println(fileName+" 不是一个合法的文件,而是一个目录");
			return ;
		}
		/*if(!file.canWrite()){
			System.out.println(fileName+" 文件不可写入");
			return ;
		}*/
		//2. 利用 对象流完成写入
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(file));
			//写入对象
			oos.writeObject(map);
			//输出一个日志
			System.out.println(">>>写入map对象成功...");
			
		} catch (IOException e) {
//			e.printStackTrace();
			//由于没有返回值,则重新抛出一个运行 时异常 
			throw new RuntimeException("序列化map失败", e);
		} finally {
			try {
				if(oos != null) oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

	/* 
	 * 此方法是从 fileName中读取一个Map的对象.
	 * @see com.tz.cels.dao.IBaseTermDao#readFromFile(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, String> readFromFile(String fileName) {
		//判断 fileName是否存在
		File file = new File(fileName);
		if(!file.exists()){
			System.out.println("文件不存在: "+fileName);
			return null;
		}
		//...
		Map<String, String> data = null;
		//
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream(file));
			//调用 readObject方法直接读到
			data = ((Map<String, String>) ois.readObject());
			
			//输出一句日志
			System.out.println(">>>读取map数据成功.");
			
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
			//失败返回null
			return null;
		} finally {
			try {
				if(ois != null) ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//正常返回
		return data;
	}

}
